package com.google.jessewilson.codesearch.ui.tree;

import com.google.jessewilson.codesearch.api.CodeFile;
import com.google.jessewilson.codesearch.api.ContentRoot;
import com.google.jessewilson.codesearch.api.Line;
import com.google.jessewilson.codesearch.api.ProgrammingLanguage;

/**
 * Any element in the search results tree.
 *
 * @author jessewilson
 */
public class Element implements Comparable<Element> {

  private Type type;
  private final ProgrammingLanguage programmingLanguage;
  private final ContentRoot contentRoot;
  private final CodeFile file;
  private final Line line;

  public Element(Type type, ProgrammingLanguage programmingLanguage,
      ContentRoot contentRoot, CodeFile file, Line line) {
    this.programmingLanguage = programmingLanguage;
    this.contentRoot = contentRoot;
    this.file = file;
    this.line = line;
    this.type = type;
  }


  public Type getType() {
    return type;
  }

  public ProgrammingLanguage getProgrammingLanguage() {
    return programmingLanguage;
  }

  public ContentRoot getContentRoot() {
    return contentRoot;
  }

  public CodeFile getFile() {
    return file;
  }

  public Line getLine() {
    return line;
  }

  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    Element element = (Element) o;
    if (contentRoot != null ? !contentRoot.equals(element.contentRoot)
        : element.contentRoot != null) {
      return false;
    }
    if (file != null ? !file.equals(element.file) : element.file != null) {
      return false;
    }
    if (line != null ? !line.equals(element.line) : element.line != null) {
      return false;
    }
    if (programmingLanguage != null ? !programmingLanguage
        .equals(element.programmingLanguage)
        : element.programmingLanguage != null) {
      return false;
    }
    if (type != element.type) {
      return false;
    }
    return true;
  }

  public int hashCode() {
    int result;
    result = (type != null ? type.hashCode() : 0);
    result = 31 * result + (programmingLanguage != null ? programmingLanguage
        .hashCode() : 0);
    result = 31 * result + (contentRoot != null ? contentRoot.hashCode() : 0);
    result = 31 * result + (file != null ? file.hashCode() : 0);
    result = 31 * result + (line != null ? line.hashCode() : 0);
    return result;
  }

  public int compareTo(Element other) {
    if (type != null) {
      int result = type.compareTo(other.type);
      if (result != 0) {
        return result;
      }
    }
    if (programmingLanguage != null) {
      int result = String.CASE_INSENSITIVE_ORDER.compare(programmingLanguage.getName(), other.programmingLanguage.getName());
      if (result != 0) {
        return result;
      }
    }
    if (contentRoot != null) {
      int result = contentRoot.compareTo(other.contentRoot);
      if (result != 0) {
        return result;
      }
    }
    if (file != null) {
      int result = file.getPath().compareTo(other.file.getPath());
      if (result != 0) {
        return result;
      }
    }
    if (line != null) {
      int result = Integer.valueOf(line.getLineNumber())
          .compareTo(Integer.valueOf(other.line.getLineNumber()));
      if (result != 0) {
        return result;
      }
    }
    return 0;
  }
}
